package dessin;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.*;
import java.io.Serializable;
import java.util.Vector;
import xdivers.Outils;
import aLeSoftware.ModeleGeneral;
import modele.*;
import xdivers.Outils;
/**
 * Cette classe sert à intercepter les actions sur le canevas et à les traiter.
 * Elle implémente MouseListener, MouseMotionListener ce qui permet de récupérer différentes actions effectuées grâce au clic.
 * Les actions effectuées dépendent de l'outil selectionné dans la ToolBar.
 * @author Arnaud
 *
 */
public class ControleurDessin implements MouseListener, MouseMotionListener, Serializable {
/**
 * Le ControleurDessin possede une instance du ModeleGeneral ce qui lui permet d'accéder aux autres modèles.
 */
	private ModeleGeneral mGeneral;
	private Point stock;
	
	/**
	 * Constructeur qui prend en parametre un ModeleGeneral md
	 * @param md
	 */
	public ControleurDessin(ModeleGeneral md) {
		this.mGeneral= md;
	}
	
	/**
	 * Retourne le ModeleGeneral
	 * @return une instance de la classe ModeleGeneral
	 */
	public ModeleGeneral getmGeneral() {return mGeneral;}

	/**
	 * Méthode appelée lorsque l'evenement est un clic simple
	 */
	public void mouseClicked(MouseEvent e) {
		
		Color couleurselection = this.mGeneral.getModPalette().getChoixColor();

		

		if (this.mGeneral.getChoixOutils() == "Point") {
			Point p = new Point(e.getX(), e.getY(),couleurselection);
			this.mGeneral.getModDessin().getGroupeDeFormes().addForme(p);
		}
		
	
		if (this.mGeneral.getChoixOutils() == "Segment") {
			FormeGeometrique f = this.mGeneral.getModDessin().getFormeTampon();
			Segment s = (Segment) f;
			
			if (s.getOrigine() == null) {
				//premier clic sur un segment
				s.setOrigine(new Point(e.getX(), e.getY()));
			} else {
				
				if(s.getExtremite()== null)
				{
					//deuxieme clic pour un segment
				s.setExtremite(new Point(e.getX(), e.getY()));
				s.setCouleur(couleurselection);
				}
				else
				{
					//les deux point sont deja défini donc c'estun nouveau segment
					s.setCouleur(this.mGeneral.getModPalette().getChoixColor());
					this.mGeneral.getModDessin().getGroupeDeFormes().addForme(s);
					s.setOrigine(new Point(e.getX(), e.getY()));
					s.setExtremite(null);
				}
			}
		}
		
		if (this.mGeneral.getChoixOutils() == "Polygone") {
			FormeGeometrique f = this.mGeneral.getModDessin().getFormeTampon();
			Polygone p = (Polygone) f;
			p.addPoint(new Point(e.getX(), e.getY()));
			p.setCouleur(couleurselection);
		}
		
		
		
		if (this.mGeneral.getChoixOutils() == "Selection") {
			Groupe candidats = this.mGeneral.getModDessin().getGroupeDeFormes();
			Point pointclic = new Point(e.getX(),e.getY());
			selectFormOfGroupOnClick(candidats, pointclic);
			}
		
		
		
		
		//dans tous les cas, dire au modele de update ses observateurs.
		this.mGeneral.updateObservateur();
	}


	public void mouseEntered(MouseEvent e) {}
	/**
	 * Méthode appelée lorsque le curseur sort du canevas
	 */
	public void mouseExited(MouseEvent e) {
		this.mGeneral.getModDessin().setCoordonnees("Out of the Canevas");
		this.mGeneral.updateObservateur();
	}
	/**
	 * Méthode appelée lorsque le clic de la souris est préssé
	 */
	public void mousePressed(MouseEvent e) {	
		Color couleurselection = this.mGeneral.getModPalette().getChoixColor();
		
		if (this.mGeneral.getChoixOutils() == "Pinceau") {
			Point p = new Point(e.getX(), e.getY(),couleurselection);
			Groupe grp = (Groupe) this.mGeneral.getModDessin().getFormeTampon();
			grp.addForme(p);
		}
		
		
		if(this.mGeneral.getChoixOutils() == "Rectangle") {
			FormeGeometrique f = this.mGeneral.getModDessin().getFormeTampon();
			Rectangle rec = (Rectangle) f;
			rec.setCouleur(couleurselection);
			rec.setPremierPoint(new Point(e.getX(), e.getY()));
			rec.setDeuxiemePoint(new Point(e.getX(), e.getY()));
			this.stock = new Point(e.getX(), e.getY());
	}	
		
		if(this.mGeneral.getChoixOutils() == "Cercle") {
			FormeGeometrique f = this.mGeneral.getModDessin().getFormeTampon();
			Cercle ce = (Cercle) f;
			ce.setCouleur(couleurselection);
			ce.setOrigine(new Point(e.getX(), e.getY()));
		}
		
		if(this.mGeneral.getChoixOutils() == "Deplacement") {
			this.stock = new Point(e.getX(), e.getY());
	}	
		
	}
	
	/**
	 * Méthode appelée lorsque le clic est préssé puis la souris déplacée (sans relacher le clic)
	 */
	@Override
	public void mouseDragged(MouseEvent e) {
		if (this.mGeneral.getChoixOutils() == "Pinceau") {
			Point p = new Point(e.getX(), e.getY(),this.mGeneral.getModPalette().getChoixColor());
			Groupe grp = (Groupe) this.mGeneral.getModDessin().getFormeTampon();
			grp.addForme(p);
		}
		
		if(this.mGeneral.getChoixOutils() == "Rectangle") {			
			FormeGeometrique f = this.mGeneral.getModDessin().getFormeTampon();
			Rectangle rec = (Rectangle) f;
			Point deuz = new Point(e.getX(), e.getY());
				rec.setDeuxiemePoint(deuz);
				rec.switchPoint(this.stock);
		}
		
		if(this.mGeneral.getChoixOutils() == "Cercle") {
			FormeGeometrique f = this.mGeneral.getModDessin().getFormeTampon();
			Cercle ce = (Cercle) f;
			ce.setRayon((int) ce.getOrigine().distance(new Point(e.getX(), e.getY())));
			}
		
		if(this.mGeneral.getChoixOutils() == "Deplacement") {
			this.mGeneral.getModDessin().decalerSelection(this.stock, new Point(e.getX(), e.getY()));
			this.stock = new Point(e.getX(), e.getY());
		}
		
		this.mGeneral.updateObservateur();	
	}
	
	/**
	 * Méthode appelée lorsque le clic de la souris est relaché
	 */
	public void mouseReleased(MouseEvent e) {
		
			if (this.mGeneral.getChoixOutils() == "Pinceau") {
			Point p = new Point(e.getX(), e.getY(),this.mGeneral.getModPalette().getChoixColor());
			Groupe grp = (Groupe) this.mGeneral.getModDessin().getFormeTampon();
			grp.addForme(p);
			this.mGeneral.getModDessin().getGroupeDeFormes().addForme(grp);
			this.mGeneral.getModDessin().setFormeTampon(new Groupe());
		}
		
		
			if(this.mGeneral.getChoixOutils() == "Rectangle") {			
			FormeGeometrique f = this.mGeneral.getModDessin().getFormeTampon();
			Rectangle rec = (Rectangle) f;
			rec.setDeuxiemePoint(new Point(e.getX(), e.getY()));
			rec.switchPoint(this.stock);
			this.mGeneral.getModDessin().getGroupeDeFormes().addForme(rec);
			rec.setPremierPoint(null);
		}
			

			if(this.mGeneral.getChoixOutils() == "Cercle") {
				FormeGeometrique f = this.mGeneral.getModDessin().getFormeTampon();
				Cercle ce = (Cercle) f;
				ce.setRayon((int) ce.getOrigine().distance(new Point(e.getX(), e.getY())));
				this.mGeneral.getModDessin().getGroupeDeFormes().addForme(ce);
				ce.setOrigine(null);
				}
			
			if(this.mGeneral.getChoixOutils() == "Deplacement") {
				this.mGeneral.getModDessin().decalerSelection(this.stock, new Point(e.getX(), e.getY()));
			}
			
			
			
			this.mGeneral.updateObservateur();	
	}
	

	/**
	 * Méthode appelée lorsque le pointeur de la souris est déplacé sur le canevas
	 */
	@Override
	public void mouseMoved(MouseEvent e) {
		
		Dimension d = this.mGeneral.getModDessin().getDimensionDessin();
		Point real = new Point(e.getX(),e.getY());
		Point adapted = Outils.RealToAdapted(real, d);
		this.mGeneral.getModDessin().setCoordonnees(adapted.getX()+" / "+adapted.getY());
		this.mGeneral.updateObservateur();
		}
	



		

	
	
	private void selectFormOfGroupOnClick(Groupe candidats, Point pointclic) {
		Vector<FormeGeometrique> vectorgroupe = candidats.getlesFormes();
		for (FormeGeometrique item : vectorgroupe) {
				if (item.isOnTheClick(pointclic)) {
					item.switchSelected();
				}	
			}
		}		

	
	


	
}
